<?php


namespace EchoPHP\Redis;

use InvalidArgumentException;

class RedisManager {

    /**
     * 应用容器链接示例
     * @var EchoPHP\Foundation\Application;
     */
    protected $app;

    /**
     * 已连接实例合集
     * @var array
     */
    protected $connections = [];

    public function __construct($app) {
        $this->app = $app;
    }

    /**
     * 析构释放redis长连接
     */
    public function __destruct() {
        foreach ($this->connections as $connection) {
            $connection->close();
        }
        $this->connections = [];
    }

    /**
     * 链接redis，获取redis链接操作器
     * @param null $name
     * @return PhpRedisConnection
     */
    public function connect($name = null) {
        $name = $this->getConnectionName($name);
        if (!isset($this->connections[$name])) {
            $this->connections[$name] = $this->makeConnection($name);
        }
        return $this->connections[$name];
    }

    /**
     * 获取默认Redis连接名称,未定义则获取默认名称
     * @param string $name
     * @return string
     */
    protected function getConnectionName($name = null) {
        if (!empty($name)) {
            return $name;
        }
        return $this->app['config']['redis.default'];
    }

    /**
     *  创建Redis连接实例
     * @param $name
     * @return \Redis
     */
    protected function makeConnection($name) {
        $config = $this->getConfiguration($name);
        $client = $this->createConnector($config);
        return $this->createConnection($client);
    }

    /**
     * 创建redis链接
     * @param $config
     * @return PhpRedisConnector
     */
    protected function createConnector($config) {
        $connector = new PhpRedisConnector();
        return $connector->connect($config);
    }

    /**
     * 创建连接器
     * @param \Redis $client
     * @return PhpRedisConnection
     */
    protected function createConnection($client) {
        return new PhpRedisConnection($client);
    }

    /**
     * 根据Redis标识获取Redis配置定义
     * @param $name
     * @return array
     */
    protected function getConfiguration($name) {
        $name = $this->getConnectionName($name);

        $config = $this->app['config']['redis.connections'];
        if (!isset($config[$name])) {
            throw new InvalidArgumentException('redis [' . $name . ']not configured');
        }
        return $config[$name];
    }

    public function __call($method, $parameters) {
        return $this->connect()->{$method}(...$parameters);
    }
}